package main

import (
	"fmt"
	"github.com/dlclark/regexp2"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var functionName string
var functionRegex *regexp.Regexp
var keyRegex *regexp2.Regexp
var valRegex *regexp2.Regexp

func main() {
	options, args := buildRunParam()

	if len(args) <= 0 {
		println("请指定需要解析的文件或文件夹")
		return
	}
	if options["fnName"] == "" {
		options["fnName"] = "__getEnvironmentFunction__"
	}

	functionName = options["fnName"]

	functionRegex = regexp.MustCompile(functionName+"\\(.*?\\)")
	keyRegex = regexp2.MustCompile(`(?<=\(('|")).*?(?=('|")\s*,)`, regexp2.None)
	valRegex = regexp2.MustCompile(`(?<=,\s*('|")).*?(?=('|")\s*\))`, regexp2.None)

	println("方法名：", functionName)

	for _,arg := range args {
		println("\t目录：", arg)
		parse(arg)
	}

	println("环境变量设置完成，共修改", len(envInfos), "个文件")

}

func parse(path string) {

	if !PathExists(path) {
		println("路径", path, "不存在")
		return
	}


	filepath.Walk(path, func (path string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			checkFile(path)
		}
		return nil
	})

	write()
}

/**
写出
 */
func write() {

	for _,info := range envInfos {
		// 写出到src
		ioutil.WriteFile(info.path+".src", []byte(info.text), 0666)
		println("文件：", info.path, "==>", info.path+".src")

		// 替换
		var text = info.text
		for _,envItem := range info.envs {
			text = strings.ReplaceAll(text, envItem.source, "'"+envItem.env+"'")
			println("\t设置环境变量：", envItem.key, "==>", envItem.env)
		}
		// 写出已替换的
		ioutil.WriteFile(info.path, []byte(text), 0666)

	}

}




func checkFile(path string)  {
	if strings.HasSuffix(path, ".src") {
		return
	}
	var srcPath = path
	if PathExists(path+".src") {
		srcPath += ".src"
	}

	content, err :=ioutil.ReadFile(srcPath)
	if err != nil {
		println("文件",srcPath, "读取错误: ", err.Error())
		return
	}
	text := string(content)

	// 查找字符串
	arr := functionRegex.FindAllString(text, -1)
	info := new(EnvInfo)
	for _,fn := range arr {

		envItem := new(EnvItem)
		envItem.source = fn
		km,err := keyRegex.FindStringMatch(fn)
		if err != nil {
			continue
		}
		envItem.key = strings.TrimSpace(km.String())
		if envItem.key == "" {
			continue
		}

		vm,_ := valRegex.FindStringMatch(fn)
		envItem.val = vm.String()


		env := os.Getenv(envItem.key)
		envItem.env = strings.TrimSpace(env)
		if env != ""{
			info.envs = append(info.envs, envItem)
		}
	}

	if len(info.envs) > 0{
		info.path = path
		info.text = text

		envInfos = append(envInfos, info)
	}
}

var envInfos []*EnvInfo

type EnvInfo struct {
	path string
	text string
	envs []*EnvItem
}

type EnvItem struct {
	key string
	val string
	source string
	env string
}

func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}
/**
  入参：第一个参数是否是 command
  返回3个参数
  param1 command
  param2 options
  param3 args
*/
func buildRunParam() (map[string]string, []string) {

	var options = make(map[string]string)
	var args []string

	sysArgs := os.Args
	if sysArgs == nil && len(sysArgs) <= 1 {
		return options, args
	}

	for i := 1; i<len(sysArgs); i++ {
		arg := sysArgs[i]
		if strings.HasPrefix(arg, "--") { // 以-为前缀的
			arr := strings.SplitN(arg, "=", 2)
			key := strings.Replace(arr[0], "--", "", 1);
			options[key] = arr[1]
		} else if strings.HasPrefix(arg, "-") { // 包含=号的
			key := strings.Replace(arg, "-", "", 1)
			i++
			if i >= len(sysArgs){
				fmt.Printf("参数【%s】没有合适的值，参数超出\n", key)
				return options, args
			}
			val := sysArgs[i]
			options[key] = val
		} else {
			args = append(args, arg)
		}
	}

	for key, val := range options {
		switch key {
		case "fn":
			options["fnName"] = val
			break
		}
	}


	return options, args
}